Skip to content

feat(ide-sync): add Kimi Code as supported IDE target - #644

Closed
dinis-prog wants to merge 1 commit into
SynkraAI:mainfrom
dinis-prog:feat/kimi-ide-integration
Closed

feat(ide-sync): add Kimi Code as supported IDE target#644
dinis-prog wants to merge 1 commit into
SynkraAI:mainfrom
dinis-prog:feat/kimi-ide-integration

Conversation

@dinis-prog

@dinis-prog dinis-prog commented Apr 30, 2026

Copy link
Copy Markdown

Summary

Adds Kimi Code (https://www.kimi-cli.com) to the IDE sync pipeline as a new target with format kimi-skill. Kimi consumes per-skill directories shaped as <skill-id>/SKILL.md and discovers them at the project Git root, so the transformer differs from the flat layouts used by Claude Code, Codex, Gemini, Cursor, and Antigravity.

Changes

  • transformers/kimi.js (new): produces SKILL.md with YAML frontmatter, ## Activation Protocol directive, persona, Star Commands table, and the full raw agent definition. Includes:
    • skillId normalization (avoids aios-aios-master double-prefix bug)
    • support for preferredActivationAlias
    • safe rendering of YAML array items that parse as objects (- CRITICAL: x was previously serialized as [object Object], regression covered by test)
  • index.js: register transformer, add kimi default target with fallbackSources: ['.codex/agents'], and emit nested <skill-id>/SKILL.md paths during sync and validation expectation building.
  • validator.js: walk markdown recursively so nested Kimi layouts are matched against expected files instead of being flagged as orphaned.
  • tests/ide-sync/kimi-transformer.test.js (new): 5 tests covering skillId rules, preferredActivationAlias, the [object Object] regression, Activation Protocol presence, and nested layout filenames.

Discovery contract

Kimi resolves project root to the nearest .git ancestor, so generated .kimi/skills/ should live at that level (or be reachable via symlink).

Test plan

  • npx jest tests/ide-sync/kimi-transformer.test.js — 5/5 PASS
  • Reviewer: npm run sync:ide -- --ide kimi --dry-run produces nested skill paths
  • Reviewer: npm run sync:ide:check -- --ide kimi passes after a fresh sync
  • Reviewer: existing IDE targets (claude-code, codex, gemini, cursor, antigravity, github-copilot) unaffected

Notes

  • No changes to other IDE targets or behaviors.
  • Validated end-to-end in a downstream workspace (Synkra-Core) with 223 agents synced and Kimi smoke tests confirming /skill:aios-* activation, MCP integration, and hooks.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for Kimi IDE format with automated transformation of agent metadata into structured skill documents containing identity, protocols, commands, and guardrails
    • Improved file organization with automatic subdirectory layout for Kimi skills based on skill identifiers
  • Tests

    • Added comprehensive test coverage for Kimi transformer validation including skill ID generation and markdown output formatting

Adds Kimi Code (https://www.kimi-cli.com) to the IDE sync pipeline as a
new target with format `kimi-skill`. Kimi consumes per-skill directories
shaped as `<skill-id>/SKILL.md` and discovers them at the project Git
root, so the transformer differs from the flat layouts used by Claude
Code, Codex, Gemini, Cursor, and Antigravity.

Changes
- transformers/kimi.js: new transformer producing SKILL.md with YAML
  frontmatter, Activation Protocol directive, persona, Star Commands
  table, and the full raw agent definition. Includes:
  - skillId normalization (avoids `aios-aios-master` double prefix)
  - support for `preferredActivationAlias`
  - safe rendering of YAML array items that parse as objects
    (`- CRITICAL: x` was previously serialized as `[object Object]`)
- index.js: register transformer, add `kimi` default target with
  `fallbackSources: ['.codex/agents']`, and write nested
  `<skill-id>/SKILL.md` paths during sync and validation expectation.
- validator.js: walk markdown recursively so nested Kimi layouts are
  matched against expected files instead of being flagged as orphaned.
- tests/ide-sync/kimi-transformer.test.js: covers skillId rules,
  preferredActivationAlias, [object Object] regression, Activation
  Protocol presence, and nested layout filenames (5/5 passing).

Discovery contract
Kimi resolves project root to the nearest `.git` ancestor, so the
generated `.kimi/skills/` should live at that level (or be reachable via
symlink). No changes to other IDE targets or behaviors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel

vercel Bot commented Apr 30, 2026

Copy link
Copy Markdown

@dinis-prog is attempting to deploy a commit to the SINKRA - AIOX Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Apr 30, 2026

Copy link
Copy Markdown

Walkthrough

This pull request introduces support for a new Kimi skill IDE format. The changes add a kimiTransformer module that converts agent metadata into structured markdown documents with identity, activation protocol, commands, and workflow sections. The sync orchestrator and validator are updated to handle nested directory structures for this format.

Changes

Cohort / File(s) Summary
Kimi Transformer Implementation
kimi.js
New transformer module that converts agent metadata into Kimi skill markdown with YAML frontmatter. Generates sections for identity, activation protocol, star commands (with auto-added directives), workflow rules, guardrails, handoffs, and agent definition. Exports helper functions for skill ID generation, directory naming, and filename derivation.
IDE Sync Core Integration
index.js
Registers the kimiTransformer and configures a new kimi target with skills directory and codex-based fallback sources. Maps kimi-skill format to the transformer. Updates sync and validate flows to use transformer.getDirname() for nested directory structure support during file generation and validation.
Orphan File Detection
validator.js
Modifies orphan-file detection to recursively walk the directory tree and collect all *.md files instead of only top-level files. Records relative paths to support nested layout validation.
Kimi Transformer Tests
kimi-transformer.test.js
New Jest test suite validating Kimi transformer behavior: skill ID prefixing with aios-, YAML array object rendering as bold key-value pairs, presence of "Activation Protocol" section, nested directory structure (filename, dirname), and format declaration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding Kimi Code as a new supported IDE target in the ide-sync infrastructure. It is concise, clear, and specific.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added area: agents Agent system related area: workflows Workflow system related squad mcp type: test Test coverage and quality area: core Core framework (.aios-core/core/) area: installer Installer and setup (packages/installer/) area: synapse SYNAPSE context engine area: cli CLI tools (bin/, packages/aios-pro-cli/) area: pro Pro features (pro/) area: health-check Health check system area: docs Documentation (docs/) area: devops CI/CD, GitHub Actions (.github/) labels Apr 30, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to aiox-core! Thanks for your first pull request.

What happens next?

  1. Automated checks will run on your PR
  2. A maintainer will review your changes
  3. Once approved, we'll merge your contribution!

PR Checklist:

Thanks for contributing!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
tests/ide-sync/kimi-transformer.test.js (1)

56-62: ⚡ Quick win

Add explicit coverage for preferred_activation_alias (snake_case).

getPreferredActivationId() supports both alias field variants; adding this test guards backward-compatibility behavior directly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/ide-sync/kimi-transformer.test.js` around lines 56 - 62, Add a new test
mirroring the existing preferredActivationAlias case but passing the snake_case
field name to ensure backward compatibility: call kimi.getSkillId with agent: {
preferred_activation_alias: 'davi-ribas' } and assert the result equals
'aios-davi-ribas'; this exercises getPreferredActivationId()'s support for both
preferredActivationAlias and preferred_activation_alias.
.aiox-core/infrastructure/scripts/ide-sync/index.js (1)

34-34: ⚡ Quick win

Use the repo’s absolute-import style for the new transformer require.

The newly added import is relative, which diverges from the project rule for JS/TS imports.

As per coding guidelines **/*.{js,jsx,ts,tsx}: "Use absolute imports instead of relative imports in all code".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.aiox-core/infrastructure/scripts/ide-sync/index.js at line 34, The require
for the new transformer uses a relative path ("./transformers/kimi"); change it
to the repository's absolute-import style while keeping the const name
kimiTransformer (i.e., replace the './transformers/kimi' module specifier with
the project's absolute module specifier that points to the same transformer), so
the import follows the repo rule of using absolute imports for JS/TS files.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.aiox-core/infrastructure/scripts/ide-sync/transformers/kimi.js:
- Around line 205-214: The loop over yaml.design_rules can throw when a value is
null because typeof null === 'object'; update the guard inside the for...of that
iterates over dr (const dr = yaml.design_rules) to ensure value is not null
before accessing value.rule (e.g., check value !== null && typeof value ===
'object' && value.rule). Make this change where the code currently checks typeof
value === 'object' and uses value.rule so null cases are safely skipped or
handled.
- Around line 302-316: getSkillId/getPreferredActivationId/getDirname currently
allow activation aliases/ids that contain "/", "\" or ".." which can enable path
traversal; sanitize the preferred activation alias (and fallback agentData.id)
by normalizing and rejecting or stripping path characters before returning a
dirname: validate the value returned by getPreferredActivationId(), remove any
path separators and parent-traversal sequences, enforce a safe character set
(e.g. alphanumerics, dash, underscore) or replace invalid chars with '-', and if
the result is empty revert to a safe fallback or throw; update getSkillId to
return the sanitized token (still prefixed with "aios-" when needed) and ensure
getDirname simply returns that sanitized skill id.

---

Nitpick comments:
In @.aiox-core/infrastructure/scripts/ide-sync/index.js:
- Line 34: The require for the new transformer uses a relative path
("./transformers/kimi"); change it to the repository's absolute-import style
while keeping the const name kimiTransformer (i.e., replace the
'./transformers/kimi' module specifier with the project's absolute module
specifier that points to the same transformer), so the import follows the repo
rule of using absolute imports for JS/TS files.

In `@tests/ide-sync/kimi-transformer.test.js`:
- Around line 56-62: Add a new test mirroring the existing
preferredActivationAlias case but passing the snake_case field name to ensure
backward compatibility: call kimi.getSkillId with agent: {
preferred_activation_alias: 'davi-ribas' } and assert the result equals
'aios-davi-ribas'; this exercises getPreferredActivationId()'s support for both
preferredActivationAlias and preferred_activation_alias.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: be53592a-04a7-4497-9337-f61259f37489

📥 Commits

Reviewing files that changed from the base of the PR and between dbb9e52 and d646b3b.

📒 Files selected for processing (4)
  • .aiox-core/infrastructure/scripts/ide-sync/index.js
  • .aiox-core/infrastructure/scripts/ide-sync/transformers/kimi.js
  • .aiox-core/infrastructure/scripts/ide-sync/validator.js
  • tests/ide-sync/kimi-transformer.test.js

Comment on lines +205 to +214
if (yaml.design_rules) {
const dr = yaml.design_rules;
let text = '### Design Rules\n\n';
for (const [key, value] of Object.entries(dr)) {
if (typeof value === 'object' && value.rule) {
text += `- **${key}:** ${value.rule}\n`;
} else if (typeof value === 'string') {
text += `- **${key}:** ${value}\n`;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Guard against null values in design_rules.

At Line 209, typeof value === 'object' is true for null, so value.rule can throw. A null check avoids transform-time failures on partially populated YAML.

✅ Minimal fix
-      if (typeof value === 'object' && value.rule) {
+      if (value && typeof value === 'object' && value.rule) {
         text += `- **${key}:** ${value.rule}\n`;
       } else if (typeof value === 'string') {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.aiox-core/infrastructure/scripts/ide-sync/transformers/kimi.js around lines
205 - 214, The loop over yaml.design_rules can throw when a value is null
because typeof null === 'object'; update the guard inside the for...of that
iterates over dr (const dr = yaml.design_rules) to ensure value is not null
before accessing value.rule (e.g., check value !== null && typeof value ===
'object' && value.rule). Make this change where the code currently checks typeof
value === 'object' and uses value.rule so null cases are safely skipped or
handled.

Comment on lines +302 to +316
function getPreferredActivationId(agentData) {
const agent = agentData.agent || {};
const preferred = agent.preferredActivationAlias || agent.preferred_activation_alias;
return String(preferred || agentData.id || '').trim();
}

function getSkillId(agentData) {
const id = getPreferredActivationId(agentData);
if (id.startsWith('aios-')) return id;
return `aios-${id}`;
}

function getDirname(agentData) {
return getSkillId(agentData);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Sanitize skillId to block path traversal via activation alias/id.

getSkillId() currently accepts /, \, and .. patterns. Since getDirname() feeds directly into path.join(...) during writes (in .aiox-core/infrastructure/scripts/ide-sync/index.js, Line 198), a crafted alias can escape .kimi/skills.

🔒 Suggested hardening patch
+function sanitizePathSegment(value) {
+  return String(value || '')
+    .trim()
+    .replace(/[\\/]+/g, '-')
+    .replace(/\.\.+/g, '-')
+    .replace(/[^a-zA-Z0-9:_-]/g, '-')
+    .replace(/-+/g, '-')
+    .replace(/^-|-$/g, '');
+}
+
 function getSkillId(agentData) {
-  const id = getPreferredActivationId(agentData);
-  if (id.startsWith('aios-')) return id;
-  return `aios-${id}`;
+  const safeId = sanitizePathSegment(getPreferredActivationId(agentData));
+  const prefixed = safeId.startsWith('aios-') ? safeId : `aios-${safeId}`;
+  return prefixed || 'aios-unknown';
 }

As per coding guidelines **/*.js: "Look for potential security vulnerabilities."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function getPreferredActivationId(agentData) {
const agent = agentData.agent || {};
const preferred = agent.preferredActivationAlias || agent.preferred_activation_alias;
return String(preferred || agentData.id || '').trim();
}
function getSkillId(agentData) {
const id = getPreferredActivationId(agentData);
if (id.startsWith('aios-')) return id;
return `aios-${id}`;
}
function getDirname(agentData) {
return getSkillId(agentData);
}
function getPreferredActivationId(agentData) {
const agent = agentData.agent || {};
const preferred = agent.preferredActivationAlias || agent.preferred_activation_alias;
return String(preferred || agentData.id || '').trim();
}
function sanitizePathSegment(value) {
return String(value || '')
.trim()
.replace(/[\\/]+/g, '-')
.replace(/\.\.+/g, '-')
.replace(/[^a-zA-Z0-9:_-]/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '');
}
function getSkillId(agentData) {
const safeId = sanitizePathSegment(getPreferredActivationId(agentData));
const prefixed = safeId.startsWith('aios-') ? safeId : `aios-${safeId}`;
return prefixed || 'aios-unknown';
}
function getDirname(agentData) {
return getSkillId(agentData);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.aiox-core/infrastructure/scripts/ide-sync/transformers/kimi.js around lines
302 - 316, getSkillId/getPreferredActivationId/getDirname currently allow
activation aliases/ids that contain "/", "\" or ".." which can enable path
traversal; sanitize the preferred activation alias (and fallback agentData.id)
by normalizing and rejecting or stripping path characters before returning a
dirname: validate the value returned by getPreferredActivationId(), remove any
path separators and parent-traversal sequences, enforce a safe character set
(e.g. alphanumerics, dash, underscore) or replace invalid chars with '-', and if
the result is empty revert to a safe fallback or throw; update getSkillId to
return the sanitized token (still prefixed with "aios-" when needed) and ensure
getDirname simply returns that sanitized skill id.

@rafaelscosta

Copy link
Copy Markdown
Collaborator

Superseded by #683.

I ported the useful Kimi IDE-sync implementation onto current main, resolved the conflicts, addressed the actionable CodeRabbit feedback, generated the .kimi/skills projection, updated the manifest/config/docs, and validated the replacement branch locally. This avoids force-pushing over the contributor fork branch while preserving the original contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: agents Agent system related area: cli CLI tools (bin/, packages/aios-pro-cli/) area: core Core framework (.aios-core/core/) area: devops CI/CD, GitHub Actions (.github/) area: docs Documentation (docs/) area: health-check Health check system area: installer Installer and setup (packages/installer/) area: pro Pro features (pro/) area: synapse SYNAPSE context engine area: workflows Workflow system related mcp squad type: test Test coverage and quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants